package connection

import (
	"game_server/framework/global"
	"github.com/duke-git/lancet/v2/maputil"
)

var _connectionManager *ConnectionManager = nil

type ConnectionManager struct {
	ConnectionPool *maputil.ConcurrentMap[int64, *ConnectionWrapper]
}

func ConnectionManagerInstance() *ConnectionManager {
	return _connectionManager
}

func InitConnectionManager() *ConnectionManager {
	connManager := &ConnectionManager{ConnectionPool: maputil.NewConcurrentMap[int64, *ConnectionWrapper](0)}
	_connectionManager = connManager
	return _connectionManager
}

func (c *ConnectionManager) AddConn(key int64, conn *ConnectionWrapper) {
	_, ok := c.ConnectionPool.Get(key)
	if !ok {
		c.ConnectionPool.Set(key, conn)
	}
	global.Logger.Infof("conn number:%v", _connectionManager.QueryConnTotal())
}

func (c *ConnectionManager) RemoveConn(key int64) {
	connectionWrapper, ok := c.ConnectionPool.Get(key)
	if !ok {
		return
	}
	if connectionWrapper.status == EXITING {
		return
	}
	connectionWrapper.release()
	c.ConnectionPool.Delete(key)
	global.Logger.Infof("======>userId:%v connection close <======", connectionWrapper.UserId)
	global.Logger.Info("conn number:", _connectionManager.QueryConnTotal())
}

func (c *ConnectionManager) QueryConnOne(key int64) *ConnectionWrapper {
	value, ok := c.ConnectionPool.Get(key)
	if ok {
		return value
	} else {
		return nil
	}
}

func (c *ConnectionManager) QueryConnMultiple(keys []int64) []*ConnectionWrapper {
	connectionWrappers := []*ConnectionWrapper{}
	for _, key := range keys {
		wrapper, ok := c.ConnectionPool.Get(key)
		if ok {
			connectionWrappers = append(connectionWrappers, wrapper)
		}
	}
	return connectionWrappers
}

func (c *ConnectionManager) QueryConnAll() *maputil.ConcurrentMap[int64, *ConnectionWrapper] {
	return c.ConnectionPool
}

func (c *ConnectionManager) QueryConnTotal() int {
	count := 0
	c.ConnectionPool.Range(func(key int64, value *ConnectionWrapper) bool {
		count++
		return true
	})
	return count
}
